﻿using System;

using System.Collections.Generic;
using System.Text;
using System.Drawing;
using Silvermoon.OpenGL.Native;
using Silvermoon.OpenGL;
using Silvermoon.Controls;
using Silvermoon.Utils;
using Silvermoon.Core;

namespace Silvermoon.Visuals
{
    /// <summary>
    /// Visual that uses TextSprite for rendering text. See also <seealso cref="ImageStringVisual"/>.
    /// </summary>
    public class StringVisual : RectangleVisual
    {

        #region Fields

        private TextSprite texture;

        #endregion
        #region ctor/dtor

        public StringVisual()
            : base()
        {
            texture = new TextSprite();
            texture.Invalidated += new EventHandler(OnTextureInvalidated);
        }

        void OnTextureInvalidated(object sender, EventArgs e)
        {
            Invalidate();
        }

        public override void Dispose()
        {
            texture.Dispose();
            base.Dispose();
        }

        #endregion
        #region Properties

        public LineMode LineMode { get { return texture.LineMode; } set { texture.LineMode = value; } }

        public Alignment Alignment { get { return texture.Alignment; } set { texture.Alignment = value; } }

        public Alignment LineAlignment { get { return texture.LineAlignment; } set { texture.LineAlignment = value; } }

        public bool Shadowed { get; set; }

        public FontSprite Font
        {
            get { return texture.Font ?? FontSprite.Regular; }
            set { texture.Font = value; }
        }


        public Size TextSize { get { return texture.TextSize; } }


        public string Text
        {
            get { return texture.Text; }
            set { texture.Text = value; }
        }



        public override Size Size
        {
            get
            {
                return texture.ClipSize;
            }
            set
            {
                texture.ClipSize = value;
            }
        }

        public int CharSpace
        {
            get { return texture.CharacterSpace; }
            set { if (texture.CharacterSpace != value) { texture.CharacterSpace = value; Invalidate(); } }
        }

        /// <summary>
        /// Gets or sets the <see cref="FontSpite"/> to use as reference to render each character refered to the specified <see cref="FontSprite"/>.
        /// </summary>
        public float ScaleFactor
        {
            get { return texture.ScaleFactor; }
            set { if (texture.ScaleFactor != value) { texture.ScaleFactor = value; Invalidate(); } }
        }


        #endregion
        #region Methods

        private static Color ShadowColor = ColorUtil.AlphaColor(Color.Black, 200);

        public override void Render(Renderer renderer)
        {

            if (Shadowed)
            {
                gl.Translatef(2f, 2f, 0f);
                int alpha = Color.A * renderer.TextColor.A;
                texture.Color = alpha != 65025 ? ColorUtil.AlphaColor(ShadowColor, (alpha * ShadowColor.A / 65025)) : ShadowColor;
                texture.Render();
                gl.Translatef(-2f, -2f, 0f);
            }
            if (Color != Color.Empty)
            {
                Color o = renderer.TextColor;
                texture.Color = o.A != 255 ? ColorUtil.AlphaColor(Color, (o.A * Color.A / 255)) : Color;
            }
            else texture.Color = renderer.TextColor;
            texture.Render();
        }


        public override void PreLoad()
        {
            base.PreLoad();
            texture.PreLoad();
        }

        public Size MeasureString(string text)
        {
            return Font.MeasureString(text);
        }

        #endregion

    }
}
